package com.dns.server.primary;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

import com.dns.message.DNS_Message;
import com.dns.util.Constants;


public class PrimaryListener {

	/**
	 * @param args
	 */
	private DatagramSocket socket;
	private Address_Lookup addressLookUp;
	private static int msg_count=0;
	public PrimaryListener(){
		socket =null;
		addressLookUp=null;
		init();
	}
	
	public void init(){
		try {
			socket= new DatagramSocket(Constants.PRIMARY_HOST_PORT);
			addressLookUp= Address_Lookup.getInstance();
		} 
		catch (SocketException e) {
			System.out.println(this.getClass().getName()+": Error : Exception while creating the server socket");
			e.printStackTrace();
		}
	}
	
	public void start(){
		byte []buff = new byte[Constants.DATA_BUFFER_SIZE];
		DatagramPacket recvdPacket;
		try{
			while(true){
				recvdPacket = new DatagramPacket(buff, buff.length);
				socket.receive(recvdPacket);
				msg_count++;
				//create a new thread and pass the pktFlow & socket to it
				DNS_Message msg =recvMessage(recvdPacket);
				RequestHandler newRequest = new RequestHandler(msg,socket,addressLookUp);
				Thread lookUpThread = new Thread(newRequest);
				lookUpThread.start();
			}
		}
		catch (IOException e) {
			System.out.println(this.getClass().getName()+": Error : Exception while receiving the packet");
			e.printStackTrace();
		}
		
	}
	
	public DNS_Message recvMessage(DatagramPacket recvdPacket){
		
		ByteArrayInputStream byteIn =null;
		ObjectInputStream objectIn = null;
		byteIn = new ByteArrayInputStream(recvdPacket.getData());
		DNS_Message msg=null;
		try{
			//String msg = new String(recvPacket.getData(),0, recvPacket.getLength());
			objectIn = new ObjectInputStream(byteIn);
			msg = (DNS_Message) objectIn.readObject();
			//System.out.println("Client IP "+recvdPacket.getAddress().getHostAddress()+" Port "+recvdPacket.getPort());
			System.out.println(this.getClass().getName()+ ": Info: Message Received : "+msg_count);
			if(msg.getMsgType()==Constants.MSG_INQUIRY)
				System.out.println(" Type : Inquiry");
			else if(msg.getMsgType()==Constants.MSG_UPDATE)
				System.out.println(" Type : Update");
			else if(msg.getMsgType()==Constants.MSG_REGISTER)
				System.out.println(" Type : Register");
			else if(msg.getMsgType()==Constants.MSG_RESPONSE)
				System.out.println(" Type : Response");

			System.out.println(" Source : "+msg.getSource()+" \n Domain Nmae : "+msg.getDomainName()+"\n IP : "+msg.getIp_address());
		}
		catch (IOException e) {
			System.out.println(this.getClass().getName()+": Error : Exception while de-serializing the DNS_Message object");
			e.printStackTrace();
		}
		catch (ClassNotFoundException e) {
			System.out.println(this.getClass().getName()+": Error : Exception while creating the deserialized DNS_Message object");
			e.printStackTrace();
		}
		finally{
			byteIn=null;
			objectIn=null;
		}
		return msg;
	}

	
	public void destroy(){
		socket.disconnect();
		socket.close();
		socket=null;
	}
	
	public static void main(String[] args) {
		PrimaryListener primaryServer = new PrimaryListener();
		primaryServer.start();
	}
}
